package com.hsjk.szwj.module.pay.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hsjk.szwj.framework.common.util.string.StringKit;
import com.hsjk.szwj.module.pay.controller.app.order.vo.QueryPayOrderResp;
import com.hsjk.szwj.module.pay.controller.app.refund.vo.QueryRefundOrderRespVO;
import com.hsjk.szwj.module.pay.controller.app.transfer.vo.QueryTransferOrderRespVO;
import com.hsjk.szwj.module.pay.dal.dataobject.config.PayOrderMchNotifyMQ;
import com.hsjk.szwj.module.pay.dal.dataobject.order.PayOrderDO;
import com.hsjk.szwj.module.pay.dal.dataobject.order.RefundOrderDO;
import com.hsjk.szwj.module.pay.dal.dataobject.order.TransferOrderDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchAppDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchInfoDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchNotifyRecordDO;
import com.hsjk.szwj.module.pay.mq.producer.PayOrderMchNotifyProducer;
import com.hsjk.szwj.module.pay.util.JeepayKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author chenjiawei
 * @desc 商户通知 service
 * @Date 2023/08/22 13:49
 **/
@Slf4j
@Service
public class PayMchNotifyService {
    @Resource
    private MchNotifyRecordService mchNotifyRecordService;
    @Resource
    private ConfigContextQueryService configContextQueryService;
    @Resource
    private PayOrderMchNotifyProducer payOrderMchNotifyProducer;
    @Resource
    private IMchInfoService mchInfoService;
    @Resource
    private IMchAppService mchAppService;

    /**
     * 商户通知信息， 只有订单是终态，才会发送通知， 如明确成功和明确失败
     **/
    public void payOrderNotify(PayOrderDO dbPayOrder) {
        log.info("payOrderNotify:{}",dbPayOrder);
        try {
            // 通知地址为空
            if (StringUtils.isEmpty(dbPayOrder.getNotifyUrl())) {
                return;
            }
            //获取到通知对象
            MchNotifyRecordDO mchNotifyRecord =
                    mchNotifyRecordService.findByPayOrder(dbPayOrder.getId());
            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }
            MchInfoDO mchInfoDO = mchInfoService.getMchInfoById(dbPayOrder.getMchId());
            MchAppDO mchAppDO = mchAppService.getById(dbPayOrder.getAppId());
            //商户app私钥
            String appSecret = configContextQueryService.
                    queryMchApp(mchInfoDO.getId(), mchAppDO.getId())
                    .getAppSecret();
            log.info("payOrderNotify:appSecret:{}",appSecret);
            // 封装通知url
            String notifyUrl = createNotifyUrl(dbPayOrder, appSecret);
            log.info("payOrderNotify:notifyUrl:{}",notifyUrl);
            mchNotifyRecord = new MchNotifyRecordDO();
            mchNotifyRecord.setOrderId(dbPayOrder.getId());
            mchNotifyRecord.setOrderType(MchNotifyRecordDO.TYPE_PAY_ORDER);
            mchNotifyRecord.setMchId(dbPayOrder.getMchId());
            //商户订单号
            mchNotifyRecord.setMchOrderId(dbPayOrder.getMchOrderId());
            mchNotifyRecord.setIsvId(dbPayOrder.getIsvId());
            mchNotifyRecord.setAppId(dbPayOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            // 通知中
            mchNotifyRecord.setState(MchNotifyRecordDO.STATE_ING);

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getId();
            payOrderMchNotifyProducer.sendMessage(
                    PayOrderMchNotifyMQ.build(notifyId, mchInfoDO.getTenantId()));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

    /**
     * 商户通知信息，退款成功的发送通知
     **/
    public void refundOrderNotify(RefundOrderDO dbRefundOrder) {

        try {
            // 通知地址为空
            if (StringUtils.isEmpty(dbRefundOrder.getNotifyUrl())) {
                return;
            }
            //获取到通知对象
            MchNotifyRecordDO mchNotifyRecord =
                    mchNotifyRecordService.findByRefundOrder(dbRefundOrder.getId());
            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }
            MchInfoDO mchInfoDO = mchInfoService.getMchInfoById(dbRefundOrder.getMchId());
            MchAppDO mchAppDO = mchAppService.getById(dbRefundOrder.getAppId());
            //商户app私钥
            String appSecret = configContextQueryService
                    .queryMchApp(mchInfoDO.getId(),
                            mchAppDO.getId()).getAppSecret();

            // 封装通知url
            String notifyUrl = createNotifyUrl(dbRefundOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecordDO();
            mchNotifyRecord.setOrderId(dbRefundOrder.getId());
            mchNotifyRecord.setOrderType(MchNotifyRecordDO.TYPE_REFUND_ORDER);
            mchNotifyRecord.setMchId(dbRefundOrder.getMchId());
            //商户订单号
            mchNotifyRecord.setMchOrderId(dbRefundOrder.getMchRefundId());
            mchNotifyRecord.setIsvId(dbRefundOrder.getIsvId());
            mchNotifyRecord.setAppId(dbRefundOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            // 通知中
            mchNotifyRecord.setState(MchNotifyRecordDO.STATE_ING);

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getId();
            payOrderMchNotifyProducer.sendMessage(
                    PayOrderMchNotifyMQ.build(notifyId, mchInfoDO.getTenantId()));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }


    /**
     * 商户通知信息，转账订单的通知接口
     **/
    public void transferOrderNotify(TransferOrderDO dbTransferOrder) {

        try {
            // 通知地址为空
            if (StringUtils.isEmpty(dbTransferOrder.getNotifyUrl())) {
                return;
            }

            //获取到通知对象
            MchNotifyRecordDO mchNotifyRecord
                    = mchNotifyRecordService.findByTransferOrder(dbTransferOrder.getId());

            if (mchNotifyRecord != null) {
                log.info("当前已存在通知消息， 不再发送。");
                return;
            }
            MchInfoDO mchInfoDO = mchInfoService.getMchInfoById(dbTransferOrder.getMchId());
            MchAppDO mchAppDO = mchAppService.getById(dbTransferOrder.getAppId());
            //商户app私钥
            String appSecret
                    = configContextQueryService
                    .queryMchApp(mchInfoDO.getId(),
                            mchAppDO.getId()).getAppSecret();

            // 封装通知url
            String notifyUrl = createNotifyUrl(dbTransferOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecordDO();
            mchNotifyRecord.setOrderId(dbTransferOrder.getId());
            mchNotifyRecord.setOrderType(MchNotifyRecordDO.TYPE_TRANSFER_ORDER);
            mchNotifyRecord.setMchId(dbTransferOrder.getMchId());
            //商户订单号
            mchNotifyRecord.setMchOrderId(dbTransferOrder.getMchOrderId());
            mchNotifyRecord.setIsvId(dbTransferOrder.getIsvId());
            mchNotifyRecord.setAppId(dbTransferOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            // 通知中
            mchNotifyRecord.setState(MchNotifyRecordDO.STATE_ING);

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getId();
            payOrderMchNotifyProducer.sendMessage(
                    PayOrderMchNotifyMQ.build(notifyId, mchInfoDO.getTenantId()));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }


    /**
     * 创建响应URL
     */
    public String createNotifyUrl(PayOrderDO payOrder, String appSecret) {

        QueryPayOrderResp queryPayOrderRS = QueryPayOrderResp.buildByPayOrder(payOrder);
        JSONObject jsonObject = JSONUtil.parseObj(queryPayOrderRS);
        //添加请求时间
        jsonObject.putIfAbsent("reqTime", System.currentTimeMillis());

        // 报文签名
        jsonObject.putIfAbsent("sign", JeepayKit.getSign(jsonObject, appSecret));
        // 生成通知
        return StringKit.appendUrlQuery(payOrder.getNotifyUrl(), jsonObject);
    }


    /**
     * 创建响应URL
     */
    public String createNotifyUrl(RefundOrderDO refundOrder, String appSecret) {

        QueryRefundOrderRespVO queryRefundOrderRS = QueryRefundOrderRespVO.buildByRefundOrder(refundOrder);
        JSONObject jsonObject = JSONUtil.parseObj(queryRefundOrderRS);
        //添加请求时间
        jsonObject.putIfAbsent("reqTime", System.currentTimeMillis());

        // 报文签名
        jsonObject.putIfAbsent("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(refundOrder.getNotifyUrl(), jsonObject);
    }


    /**
     * 创建响应URL
     */
    public String createNotifyUrl(TransferOrderDO transferOrder, String appSecret) {

        QueryTransferOrderRespVO rs = QueryTransferOrderRespVO.buildByRecord(transferOrder);
        JSONObject jsonObject = JSONUtil.parseObj(rs);
        //添加请求时间
        jsonObject.putIfAbsent("reqTime", System.currentTimeMillis());

        // 报文签名
        jsonObject.putIfAbsent("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(transferOrder.getNotifyUrl(), jsonObject);
    }


    /**
     * 创建响应URL
     */
    public String createReturnUrl(PayOrderDO payOrder, String appSecret) {

        if (StringUtils.isEmpty(payOrder.getReturnUrl())) {
            return "";
        }

        QueryPayOrderResp queryPayOrderRS = QueryPayOrderResp.buildByPayOrder(payOrder);
        JSONObject jsonObject = JSONUtil.parseObj(queryPayOrderRS);
        //添加请求时间
        jsonObject.putIfAbsent("reqTime", System.currentTimeMillis());

        // 报文签名  // 签名
        jsonObject.putIfAbsent("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成跳转地址
        return StringKit.appendUrlQuery(payOrder.getReturnUrl(), jsonObject);

    }
}
